package com.leemon.mall.common.filter;

import com.leemon.mall.common.xss.XssWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author limenglong
 * @create 2019-09-05 18:27
 * @desc Xss攻击过滤
 **/
@Slf4j
@Configuration
@WebFilter(filterName = "XssFilter", urlPatterns = "/*", asyncSupported = true)
public class XssFilter implements Filter {

    private static boolean IS_INCLUDE_RICH_TEXT = false;
    private List<String> excludes = new ArrayList<>();


    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        if (handleExcludeUrl(req, resp)) {
            chain.doFilter(request, response);
            return;
        }

        log.info("对uri进行Xss防御过滤，uri:{}", req.getRequestURI());
        chain.doFilter(new XssWrapper(req, IS_INCLUDE_RICH_TEXT), resp);
    }


    private boolean handleExcludeUrl(HttpServletRequest request, HttpServletResponse response) {

        if (CollectionUtils.isEmpty(excludes)) {
            return false;
        }

        String url = request.getServletPath();
        for (String pattern : excludes) {
            Pattern p = Pattern.compile("^" + pattern);
            Matcher m = p.matcher(url);
            if (m.find()) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("XssFilter初始化...");
        String isIncludeRichText = filterConfig.getInitParameter("isIncludeRichText");

        if (StringUtils.isNotBlank(isIncludeRichText)) {
            IS_INCLUDE_RICH_TEXT = BooleanUtils.toBoolean(isIncludeRichText);
        }

        String temp = filterConfig.getInitParameter("excludes");
        if (StringUtils.isNotBlank(temp)) {
            String[] url = StringUtils.split(temp, ",");
            for (int i = 0; url != null && i < url.length; i++) {
                excludes.add(url[i]);
            }
        }
    }
}
